package cn.com.wxd.common.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.wxd.common.DateUtil;

/**
 * Title:文件工具类
 * Description:用于快速的处理一些文件的操作
 * <p>
 * Company: Amumu管理平台
 * Copyright: Copyright (c) 2015
 * All right reserved.
 * Created time: 2015-12-14 下午4:30:34
 *
 * @author WangXuDong
 * @version 1.0
 */
public class MyFileUtil {
    private static final Logger log = LoggerFactory.getLogger(MyFileUtil.class);

    /**
     * 删除文件夹及其子文件
     * 使用递归解决了java在文件夹内有文件是无法删除的问题。
     *
     * @param file 对象
     */
    public static boolean deleteAllFilesOfDir(File file) throws IOException {
        if (!file.exists()) {
            return true;
        }
        if (file.isFile()) {
            file.delete();
            return true;
        }
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            deleteAllFilesOfDir(files[i]);
        }
        return file.delete();
    }

    /**
     * 文件重命名
     *
     * @param path    文件目录
     * @param oldname 原来的文件名
     * @param newname 新文件名
     *
     * @throws IOException
     */
    public static boolean renameFile(String path, String oldname, String newname) throws IOException {
        if (!oldname.equals(newname)) {//新的文件名和以前文件名不同时,才有必要进行重命名
            File oldfile = new File(path + File.separator + oldname);
            File newfile = new File(path + File.separator + newname);
            if (!oldfile.exists()) {
                log.error("文件重命名错误!文件不存在!");
                throw new IOException("文件不存在" + oldfile.getName());
            }
            //若在该目录下已经有一个文件和新文件名相同，则不允许重命名
            if (newfile.exists()) {
                log.error("文件重命名错误!已存在 '" + newname + "' 名称的文件!");
                throw new IOException("文件重命名错误!已存在 '" + newname + "' 名称的文件!");
            } else {
                return oldfile.renameTo(newfile);
            }
        }
        return true;
    }

    /**
     * 删除一个指定的文件
     *
     * @param file
     *
     * @return 0成功 -1不存在 1删除异常
     */
    public static int deleteFile(File file) {
        if (file != null) {
            try {
                if (!file.exists()) {
                    return -1;
                }
                if (file.isFile()) {
                    file.delete();
                    return 0;
                } else {
                    return -1;
                }
            } catch (Exception e) {
                log.error("Delete File Exception!" + e.getMessage());
                return 1;
            }
        } else {
            return 1;
        }

    }

    /**
     * 文件的复制
     *
     * @param sourceFile 源文件
     * @param newFile    新文件
     *
     * @throws IOException
     */
    public static boolean fileChannelCopy(File sourceFile, File newFile) throws IOException {
        if (!sourceFile.exists() || sourceFile.isDirectory()) {
            log.warn("文件无法复制，因为指定的地址不是文件而是目录。");
            return false;
        }
        if (!newFile.exists() || newFile.isDirectory()) {
            try {
                newFile.createNewFile();
            } catch (IOException e) {
                log.error(DateUtil.getDatetimeStr() + "Create File Failure!", e);
                throw e;
            }
        }
        FileInputStream fi = null;
        FileOutputStream fo = null;
        FileChannel in = null;
        FileChannel out = null;
        try {
            //使用nid进行文件的复制，将几乎不会影响内存。
            fi = new FileInputStream(sourceFile);
            fo = new FileOutputStream(newFile);
            in = fi.getChannel();//得到对应的文件通道
            out = fo.getChannel();//得到对应的文件通道
            in.transferTo(0, in.size(), out);//连接两个通道，并且从in通道读取，然后写入out通道
            return true;
        } catch (IOException e) {
            log.error(DateUtil.getDatetimeStr() + "Copy File Error", e);
            throw e;
        } finally {
            try {
                fi.close();
                in.close();
                fo.close();
                out.close();
            } catch (IOException e) {
                log.error(DateUtil.getDatetimeStr() + "FileStream closed Failire", e);
            }

        }
    }

    /**
     * 删除指定目录及文件
     *
     * @param dir
     *
     * @throws IOException
     */
    public static void deleteDirectory(File dir) throws IOException {
        if ((dir == null) || !dir.isDirectory()) {
            throw new IllegalArgumentException("Argument " + dir
                    + " is not a directory. ");
        }
        File[] entries = dir.listFiles();
        int sz = entries.length;
        for (int i = 0; i < sz; i++) {
            if (entries[i].isDirectory()) {
                deleteDirectory(entries[i]);
            } else {
                entries[i].delete();
            }
        }
        dir.delete();
    }
}
